package common.project.epic.ui;

import java.io.File;
import java.text.DateFormat;

import common.project.epic.db.CurrentUser;
import common.project.epic.db.EpicDBAdapter;

import android.app.Activity;
import android.app.Dialog;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.database.Cursor;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.Bundle;
import android.text.method.ScrollingMovementMethod;
import android.text.util.Linkify;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.RatingBar;
import android.widget.RatingBar.OnRatingBarChangeListener;
import android.widget.TextView;
import android.widget.Toast;

public class EpicShowMsg extends Activity implements OnClickListener {
	public static final String TAG = "Epic: EpicShowMsg Activity";
    public static final boolean DEBUG = EpicDebugUI.DEBUG;

    public static final int NUMBER_OF_CATEGORIES = 16;
    
    private TextView creatorLink_TV;
    private TextView rxRating_TV;
    
    private TextView title;
	private TextView content;
	
	private boolean[] msg_categories = new boolean[NUMBER_OF_CATEGORIES];
	private static final String[] list_of_categories = {"General","Leisure","Advertisements","Suggestions",
														"Events","NONE","NONE","NONE",
														"NONE","NONE","NONE","NONE",
														"NONE","NONE","NONE","NONE"};
	
	private ImageButton categories_IB;
	private ImageButton attachments_IB;
	private ImageButton geo_info_IB;
	private ImageButton time_info_IB;
	
	private RatingBar ratingbar;
	private double rxRate;
	private double myRate;
	
	private final int CATEGORIES_MENU_ID = 1;
	private final int ATTACHMENTS_MENU_ID = 2;
	private final int GEO_INFO_MENU_ID = 3;
	private final int TIME_INFO_MENU_ID = 4;
	private static final int DIALOG_RATING = 5;
	// set rating Dialog
    private Dialog dialogRating;
    // set rating Dialog dismiss() Button
 	private Button dialogRatingDismissButton;
    private IconContextMenu iconContextMenu_categories = null;
    private IconContextMenu iconContextMenu_attachments = null;
    private IconContextMenu iconContextMenu_geo_info = null;
    private IconContextMenu iconContextMenu_time_info = null;
	
    private String msg_id;
    
    private String extra_extension;
    private String extra_content;
    private String[] extra_extension_array;
    private String[] extra_content_array;
    
    private String msg_creator_account_id;
    
    private int msg_geo_span;
    private double msg_geo_lat;
    private double msg_geo_lon;
    private double msg_geo_alt;
    
    private long msg_expire_time;
    
    private String delivery_account_id;
    private long delivery_time;
    private double delivery_geo_lat;
    private double delivery_geo_lon;
    private double delivery_geo_alt;
    
    private Resources res;
    
    private EpicDBAdapter dbHelper;
    private Cursor cursor;
    String msg_id_to_query;
    
    Intent mapIntent;
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.epicshowmsg);
        
        res = getResources();
        
        if(DEBUG) {Log.d(TAG, "onCreate()");}
        mapIntent = new Intent(this, EpicMapActivity.class);
        
        Intent  callingIntent = getIntent();
        msg_id_to_query = callingIntent.getStringExtra("msg_id_to_query");
    }
    
    @Override
    public void onResume(){
    	super.onResume();
    	
    	res = getResources();

        if(dbHelper==null) {
        	dbHelper = new EpicDBAdapter(this);
        }
        dbHelper.open();
        
        cursor = dbHelper.getContent(msg_id_to_query);
        if(cursor!=null) {
        	if(cursor.getCount()>1) {
        		Log.d(TAG, "Error: found not unique message!");
        		Toast.makeText(getApplicationContext(), "Error: found not unique message!", Toast.LENGTH_LONG).show();
        		finish();
        	}
        	else {
        		initialize();
        	}
        }
        else {
        	Toast.makeText(getApplicationContext(), "Problem in retrieving the message", Toast.LENGTH_LONG).show();
        	finish();
        }
    }
    
    @Override
    public void onPause(){
    	if (dbHelper != null) {
			dbHelper.close();
		}
    	super.onPause();
    }
    
    //###############################################################
    @Override
    public void onSaveInstanceState(Bundle savedInstanceState) {
    	// Save UI state changes to the savedInstanceState.
    	// This bundle will be passed to onCreate if the process is
    	// killed and restarted.
    	savedInstanceState.putString("msg_id_to_query", msg_id_to_query);
    	
    	savedInstanceState.putDouble("rxRate", rxRate);
    	savedInstanceState.putDouble("myRate", myRate);
    	
    	savedInstanceState.putString("msg_id", msg_id);
    	
    	savedInstanceState.putLong("msg_expire_time", msg_expire_time);
    	savedInstanceState.putDouble("msg_geo_lat", msg_geo_lat);
    	savedInstanceState.putDouble("msg_geo_lon", msg_geo_lon);
    	savedInstanceState.putDouble("msg_geo_alt", msg_geo_alt);
    	savedInstanceState.putInt("msg_geo_span", msg_geo_span);
    	savedInstanceState.putBooleanArray("msg_categories", msg_categories);
    	savedInstanceState.putString("msg_creator_account_id", msg_creator_account_id);
    	savedInstanceState.putString("extra_extension", extra_extension);
    	savedInstanceState.putString("extra_content", extra_content);
    	savedInstanceState.putString("delivery_account_id", delivery_account_id);
    	savedInstanceState.putLong("delivery_time", delivery_time);
    	savedInstanceState.putDouble("delivery_geo_lat", delivery_geo_lat);
    	savedInstanceState.putDouble("delivery_geo_lon", delivery_geo_lon);
    	savedInstanceState.putDouble("delivery_geo_alt", delivery_geo_alt);
    	
    	super.onSaveInstanceState(savedInstanceState);
    }

    @Override
    public void onRestoreInstanceState(Bundle savedInstanceState) {
    	super.onRestoreInstanceState(savedInstanceState);
    	// Restore UI state from the savedInstanceState.
    	// This bundle has also been passed to onCreate.
    	msg_id_to_query = savedInstanceState.getString("msg_id_to_query");
    	
    	rxRate = savedInstanceState.getDouble("rxRate");
    	myRate = savedInstanceState.getDouble("myRate");
    	
    	msg_id = savedInstanceState.getString("msg_id");
    	
    	msg_expire_time = savedInstanceState.getLong("msg_expire_time");
    	msg_geo_lat = savedInstanceState.getDouble("msg_geo_lat");
    	msg_geo_lon = savedInstanceState.getDouble("msg_geo_lon");
    	msg_geo_alt = savedInstanceState.getDouble("msg_geo_alt");
    	msg_geo_span = savedInstanceState.getInt("msg_geo_span");
    	msg_categories = savedInstanceState.getBooleanArray("msg_categories");
    	msg_creator_account_id = savedInstanceState.getString("msg_creator_account_id");
    	extra_extension = savedInstanceState.getString("extra_extension");
    	extra_content = savedInstanceState.getString("extra_content");
    	delivery_account_id = savedInstanceState.getString("delivery_account_id");
    	delivery_time = savedInstanceState.getLong("delivery_time");
    	delivery_geo_lat = savedInstanceState.getDouble("delivery_geo_lat");
    	delivery_geo_lon = savedInstanceState.getDouble("delivery_geo_lon");
    	delivery_geo_alt = savedInstanceState.getDouble("delivery_geo_alt");
    }
    //###############################################################
    
    private void initialize() {
    	
    	dbHelper.markAsRead(msg_id_to_query);
    	
    	creatorLink_TV = (TextView) findViewById(R.id.epicshowmsg_creatorLink_TV);
    	rxRating_TV = (TextView) findViewById(R.id.epicshowmsg_rxRating_TV);
    	
    	title = (TextView) findViewById(R.id.epicshowmsg_title_TV);
    	title.setMovementMethod(new ScrollingMovementMethod());
    	content = (TextView) findViewById(R.id.epicshowmsg_content_TV);
    	content.setMovementMethod(new ScrollingMovementMethod());
    	categories_IB =  (ImageButton) findViewById(R.id.epicshowmsg_categories_IB);
    	attachments_IB = (ImageButton) findViewById(R.id.epicshowmsg_attach_IB);
    	geo_info_IB =  (ImageButton) findViewById(R.id.epicshowmsg_geo_IB);
    	time_info_IB = (ImageButton) findViewById(R.id.epicshowmsg_time_IB);
    	
    	rxRate = cursor.getDouble(cursor.getColumnIndex(EpicDBAdapter.MSG_COPY_RATE));
    	myRate = cursor.getDouble(cursor.getColumnIndex(EpicDBAdapter.MY_RATE));
    	
    	msg_id = cursor.getString(cursor.getColumnIndex(EpicDBAdapter.MSG_ID));
    	
    	msg_expire_time = cursor.getLong(cursor.getColumnIndex(EpicDBAdapter.MSG_EXP_TIME));
    	
		msg_geo_lat = cursor.getDouble(cursor.getColumnIndex(EpicDBAdapter.MSG_GEO_LAT));
		msg_geo_lon = cursor.getDouble(cursor.getColumnIndex(EpicDBAdapter.MSG_GEO_LON));
		msg_geo_alt = cursor.getDouble(cursor.getColumnIndex(EpicDBAdapter.MSG_GEO_ALT));
		msg_geo_span = cursor.getInt(cursor.getColumnIndex(EpicDBAdapter.MSG_GEO_SPAN));
		
//		result = someCondition ? value1 : value2;
		msg_categories[0] = (cursor.getInt(cursor.getColumnIndex(EpicDBAdapter.MSG_CATEGORY_GENERAL))==1) ? true : false;
		msg_categories[1] = (cursor.getInt(cursor.getColumnIndex(EpicDBAdapter.MSG_CATEGORY_GAMES))==1) ? true : false;
		msg_categories[2] = (cursor.getInt(cursor.getColumnIndex(EpicDBAdapter.MSG_CATEGORY_ADVERTISEMENTS))==1) ? true : false;
		msg_categories[3] = (cursor.getInt(cursor.getColumnIndex(EpicDBAdapter.MSG_CATEGORY_SUGGESTIONS))==1) ? true : false;
		msg_categories[4] = (cursor.getInt(cursor.getColumnIndex(EpicDBAdapter.MSG_CATEGORY_EVENTS))==1) ? true : false;
		
		msg_creator_account_id = cursor.getString(cursor.getColumnIndex(EpicDBAdapter.MSG_CREATOR_ID));
		
		creatorLink_TV.setText(cursor.getString(cursor.getColumnIndex(EpicDBAdapter.CREATOR_NICK_NAME)));
		rxRating_TV.setText("Message rating: " + rxRate);
		
		title.setText(cursor.getString(cursor.getColumnIndex(EpicDBAdapter.MSG_TITLE)));
		Linkify.addLinks(title, Linkify.ALL);
		content.setText(cursor.getString(cursor.getColumnIndex(EpicDBAdapter.MSG_CONTENT)));
		Linkify.addLinks(content, Linkify.ALL);
		
		extra_extension = cursor.getString(cursor.getColumnIndex(EpicDBAdapter.MSG_EXTRA_TYPE));
		extra_content = cursor.getString(cursor.getColumnIndex(EpicDBAdapter.MSG_EXTRA_CONTENT));
		
		delivery_account_id = cursor.getString(cursor.getColumnIndex(EpicDBAdapter.MSG_DEL_ID));
		delivery_time = cursor.getLong(cursor.getColumnIndex(EpicDBAdapter.MSG_DEL_TIME));
		delivery_geo_lat = cursor.getDouble(cursor.getColumnIndex(EpicDBAdapter.MSG_DEL_LAT));
		delivery_geo_lon = cursor.getDouble(cursor.getColumnIndex(EpicDBAdapter.MSG_DEL_LON));
		delivery_geo_alt = cursor.getDouble(cursor.getColumnIndex(EpicDBAdapter.MSG_DEL_ALT));
		
		creatorLink_TV.setOnClickListener(this);
		
		categories_IB.setOnClickListener(this);
		attachments_IB.setOnClickListener(this);
    	geo_info_IB.setOnClickListener(this);
    	time_info_IB.setOnClickListener(this);
    }
    
    @Override
	public void onClick(View v) {
		if(v.getId() == R.id.epicshowmsg_categories_IB) {
			showCategoriesMenu();
		}
		if(v.getId() == R.id.epicshowmsg_attach_IB) {
			showAttachmentsMenu();
		}
		if(v.getId() == R.id.epicshowmsg_geo_IB) {
			showGeoInfoMenu();
		}
		if(v.getId() == R.id.epicshowmsg_time_IB) {
			showTimeInfoMenu();
		}
		if(v.getId() == R.id.epicshowmsg_creatorLink_TV) {
			// TODO redirect to the creator web profile
			Toast.makeText(getApplicationContext(), "redirect to creator web profile", Toast.LENGTH_LONG).show();
//			String creatorId = cursor.getString(cursor.getColumnIndex(EpicDBAdapter.MSG_CREATOR_ID));
//			String url = "http://www.epic-app.com/" + creatorId;
//			Intent i = new Intent(Intent.ACTION_VIEW);
//			i.setData(Uri.parse(url));
//			startActivity(i);
		}
		if(v.getId() == R.id.dialogRatingDismissButton) {
//			Log.d(TAG, "New Rating: " + myRate);
	    	dbHelper.setMyRating(msg_id, myRate);
	    	dbHelper.markAsNotUpdated(msg_id);
			dialogRating.dismiss();
		}
    }
    
    @Override
    protected Dialog onCreateDialog(int id) {
    	
        if(id == CATEGORIES_MENU_ID) {
        	if(iconContextMenu_categories==null) {
        		iconContextMenu_categories = new IconContextMenu(this, CATEGORIES_MENU_ID);
    		    int ii = 0;
    		    for(int i=0; i<NUMBER_OF_CATEGORIES; i++) {
    		    	if(msg_categories[i]) {
    		    		iconContextMenu_categories.addItem(res, list_of_categories[i], R.drawable.icon, ii);
    		    		ii++;
    		    	}
    		    }
        	}
        	return iconContextMenu_categories.createMenu(res, R.string.categories);
        }
        
        
        if(id == ATTACHMENTS_MENU_ID) {
        	// initialize the LIST_OF_ATTACHMENTS context menu
        	if(iconContextMenu_attachments==null) {
        		iconContextMenu_attachments = new IconContextMenu(this, ATTACHMENTS_MENU_ID);
    		    if(extra_extension==null && extra_content==null) {
    		    	iconContextMenu_attachments.addItem(res, "No attachments", R.drawable.icon, 0);
    		    }
    		    else {
    		    	extra_extension_array = extra_extension.split(",");
    		    	extra_content_array = extra_content.split(",");
    		    	int count_occurrence = extra_content_array.length;
    		    	for(int i=0; i<count_occurrence; i++) {
    		    		iconContextMenu_attachments.addItem(res, 
    		    				extra_content_array[i].split("/")[(extra_content_array[i].split("/")).length-1], R.drawable.icon, i);
    		    	}
    		    }
        	}
        	iconContextMenu_attachments.setOnClickListener(new IconContextMenu.IconContextMenuOnClickListener() {
                public void onClick(int item_id) {
                	if(!(extra_extension==null && extra_content==null)) {
    	            	Intent intent_view_attachment = new Intent();  
    	            	intent_view_attachment.setAction(android.content.Intent.ACTION_VIEW);
    	            	
    	            	File file = new File(extra_content_array[item_id]);
    	                Uri uri = Uri.fromFile(file);
    	                
    	                String fileExtension = android.webkit.MimeTypeMap.getFileExtensionFromUrl(extra_content_array[item_id]);
    	                String mimeType = android.webkit.MimeTypeMap.getSingleton().getMimeTypeFromExtension(fileExtension);
    	            	
    	                intent_view_attachment.setDataAndType(uri, mimeType);
    	                
    	                try {
    	                	startActivity(intent_view_attachment);
    	                }
    	                catch (ActivityNotFoundException e) {
    	                    e.printStackTrace();
    	                    Toast.makeText(getApplicationContext(), "Unable to open this file", Toast.LENGTH_LONG).show();
    	                }
                	}
                	else {
                		Toast.makeText(getApplicationContext(), "No attachments", Toast.LENGTH_LONG).show();
                	}
                }
    	    });
        	return iconContextMenu_attachments.createMenu(res, R.string.attachments);
        }
        
        
        if(id == GEO_INFO_MENU_ID) {
        	if(iconContextMenu_geo_info==null) {
        		iconContextMenu_geo_info = new IconContextMenu(this, GEO_INFO_MENU_ID);
        		iconContextMenu_geo_info.addItem(res,"See map", R.drawable.icon, 0);
    		    iconContextMenu_geo_info.addItem(res, "GPS\nN: " + msg_geo_lon + "\nW: " + msg_geo_lat, R.drawable.icon, 1);
    		    if(msg_geo_span == 10) {
    		    	iconContextMenu_geo_info.addItem(res, "Blowing strenght: building", R.drawable.icon, 2);
    		    }
    		    else if(msg_geo_span == 100) {
    		    	iconContextMenu_geo_info.addItem(res, "Blowing strenght: quarter", R.drawable.icon, 2);
    		    }
    		    else if(msg_geo_span == 1000) {
    		    	iconContextMenu_geo_info.addItem(res, "Blowing strenght: city", R.drawable.icon, 2);
    		    }
    		    else if(msg_geo_span == 65000) {
    		    	iconContextMenu_geo_info.addItem(res, "Blowing strenght: world", R.drawable.icon, 2);
    		    }
    		    else {
    		    	iconContextMenu_geo_info.addItem(res, "Blowing strenght: " + (msg_geo_span*10) + " [meters]", R.drawable.icon, 2);
    		    }
        	}
        	iconContextMenu_geo_info.setOnClickListener(new IconContextMenu.IconContextMenuOnClickListener() {
                public void onClick(int item_id) {
                	if(item_id==0) {
                		if(msg_geo_lat==0 && msg_geo_lon==0) {
                			Toast.makeText(getApplicationContext(), "Message with no origin specified", Toast.LENGTH_LONG).show();
                		}
                		else {
		            		if(isOnline()) {
		    					mapIntent.putExtra("inLat", msg_geo_lat);
		    					mapIntent.putExtra("inLon", msg_geo_lon);
		    					mapIntent.putExtra("settableMsgPosition", false);
		    					startActivity(mapIntent);
		        			}
		        			else {
		        				Toast.makeText(getApplicationContext(), "Data connection is needed", Toast.LENGTH_LONG).show();
		        			}
                		}
                	}
                }
    	    });
        	return iconContextMenu_geo_info.createMenu(res, R.string.geo_info);
        }
        
        
        if(id == TIME_INFO_MENU_ID) {
        	if(iconContextMenu_time_info==null) {
        		iconContextMenu_time_info = new IconContextMenu(this, TIME_INFO_MENU_ID);
    	    	String creation_time_str = msg_id.substring(4);
    	    	long creation_time_in_seconds = (long) Double.parseDouble(creation_time_str);
    	    	long creation_time_in_millis = creation_time_in_seconds*1000;
    	    	creation_time_str = DateFormat.getDateInstance().format(creation_time_in_millis);
    	    	
    	    	long expire_time_in_millis = msg_expire_time*1000; // msg_expire_time [s]
    	    	String expire_time_str = DateFormat.getDateInstance().format(expire_time_in_millis);
    	    	
    	//    	SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ssZZZZ");
    	//    	Date gmt = formatter.parse("2011-07-19T18:23:20+0000");
    	//    	long millisecondsSinceEpoch0 = gmt.getTime();
    	//    	String asString = formatter.format(gmt);
    		    iconContextMenu_time_info.addItem(res, "Blooming: " + creation_time_str, R.drawable.icon, 0);
    		    iconContextMenu_time_info.addItem(res, "Withering: " + expire_time_str, R.drawable.icon, 1);
        	}
        	return iconContextMenu_time_info.createMenu(res, R.string.time_info);
        }
        
        if(id == DIALOG_RATING) {
    		if(dialogRating==null) {
	            dialogRating = new Dialog(this);
				dialogRating.setContentView(R.layout.rate_message_dialog);
				dialogRating.setTitle("Rate the message");
	            
				dialogRatingDismissButton = (Button)dialogRating.findViewById(R.id.dialogRatingDismissButton);
				dialogRatingDismissButton.setOnClickListener(this);
				
				ratingbar = (RatingBar)dialogRating.findViewById(R.id.epicshowmsg_ratingbar);
				ratingbar.setRating((float) myRate);
		    	ratingbar.setOnRatingBarChangeListener(new OnRatingBarChangeListener() {
		    	    public void onRatingChanged(RatingBar ratingBar, float rating, boolean fromUser) {
		    	    	myRate = rating;
		    	    	Log.d("EpicShowMsg", "rating: " + rating);
		    	    }
		    	});
	    	}
    		return dialogRating;
        }
        
        return super.onCreateDialog(id);
    }
    
    
    public void showCategoriesMenu() {
    	showDialog(CATEGORIES_MENU_ID);
    }
    
    public void showAttachmentsMenu() {
    	showDialog(ATTACHMENTS_MENU_ID);
    }
    

    public void showGeoInfoMenu() {
    	showDialog(GEO_INFO_MENU_ID);
    }
    
    public void showTimeInfoMenu() {
    	showDialog(TIME_INFO_MENU_ID);
    }
    
    //#################
    //## OPTION MENU ##
    //#################
    @Override
	public boolean onCreateOptionsMenu(Menu menu) {
	    MenuInflater inflater = getMenuInflater();
	    inflater.inflate(R.menu.remove_or_rate_element_menu, menu);
	    return true;
	}
	
	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
	    // Handle item selection
	    switch (item.getItemId()) {
	    case R.id.delete_msg: {
	    	if(dbHelper!=null) {
	        	dbHelper.open();
	        }
	        else {
	        	dbHelper = new EpicDBAdapter(this);
	        	dbHelper.open();
	        }
	    	boolean deletionSucceeded = dbHelper.markAsDeleted(msg_id);
	    	if(deletionSucceeded) {
	    		Log.d("EpicShowMsg", "Epic message marked as deleted.");
	    	}
	    	else {
	    		Log.d("EpicShowMsg", "Error in deleting this Epic message!");
	    	}
	    	finish();
	        return deletionSucceeded;
	    }
	    case R.id.rate_msg: {
	    	CurrentUser.readCurrentUserSettings(getApplicationContext());
	    	if(CurrentUser.getMd5ID(getApplicationContext()).equals(msg_creator_account_id)) {
	    		Toast.makeText(getApplicationContext(), "Since you are the creator of this message " +
	    				"you are not allowed to rate it", Toast.LENGTH_LONG).show();
	    	}
	    	else {
	    		showDialog(DIALOG_RATING);
	    	}
	        return true;
	    }
	    default:
	        return super.onOptionsItemSelected(item);
	    }
	}
	
	// check if there is data connection
	public boolean isOnline() {
		ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
		NetworkInfo ni = cm.getActiveNetworkInfo();
		if(ni != null){
			return cm.getActiveNetworkInfo().isConnectedOrConnecting();
		}
		else {
			return false;
		}
	}
	
}